package com.example.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.constant.MessageConstant;
import com.example.context.BaseContext;
import com.example.dto.PageDTO;
import com.example.dto.ReportDTO;
import com.example.entity.Comment;
import com.example.entity.Report;
import com.example.mapper.ReportMapper;
import com.example.query.PageQuery;
import com.example.query.ReportQuery;
import com.example.result.Result;
import com.example.service.ICommentService;
import com.example.service.IReportService;
import com.example.vo.ReportVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;


@Service
@RequiredArgsConstructor
public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> implements IReportService {

    private final ICommentService commentService;

    /*
     * 新增举报
     * @param reportDTO
     * @return
     * */
    @Override
    public void addReport(ReportDTO reportDTO) {
        Long commentId = checkCommentExist(reportDTO);
        //判断是否已经举报过了
        Long count = lambdaQuery()
                .eq(Report::getCommentId, commentId)
                .eq(Report::getUserId, reportDTO.getUserId())
                .eq(Report::getStatus, 1)
                .count();
        if (count > 0) {
            throw new RuntimeException(MessageConstant.USER_HAS_REPORTED);
        }
        //举报内容不能为空
        if (reportDTO.getReason() == null) {
            throw new RuntimeException(MessageConstant.REPORT_CONTENT_NOT_NULL);
        }
        //封装数据
        Report report = Report.builder()
                .commentId(reportDTO.getCommentId())
                .userId(BaseContext.getCurrentId())
                .reason(reportDTO.getReason())
                .build();
        save(report);
    }



    /*
     * 查询举报列表
     * @param pageQuery
     * @return
     * */
    @Override
    public Result<PageDTO<ReportVO>> QueryReportpage(ReportQuery reportQuery) {
        Long userId = reportQuery.getUserId();
        //构造分页对象
        Page<Report> page = reportQuery.toMpPage("status");
        //构造查询条件
        Page<Report> p = lambdaQuery()
                .eq(userId != null, Report::getUserId, userId)
                .page(page);
        //转换为VO
        PageDTO<ReportVO> pageDTO = PageDTO.of(p, ReportVO.class);
        return Result.success(pageDTO);
    }

    /*
    * 举报审核
    * @param reportDTO
    * @return
    * */
    @Override
    public void checkReport(ReportDTO reportDTO) {
        Long commentId = checkCommentExist(reportDTO);

        if (reportDTO.getFlag() == 2) {
            lambdaUpdate()
                    .eq(Report::getId, reportDTO.getId())
                    .set(Report::getStatus, 2)
                    .update();
        } else if (reportDTO.getFlag() == 1) {
            lambdaUpdate()
                    .eq(Report::getCommentId, commentId)
                    .set(Report::getStatus, 2)
                    .update();
            commentService.removeComment(commentId);
        }
    }

    /*
    * 获取举报详情
    * @param id
    * @return
    * */
    @Override
    public ReportVO getDetails(Long id) {
        Report report = getById(id);
        Long commentId = report.getCommentId();
        Comment comment = commentService.getById(commentId);
        //检查评论是否被删除
        ReportDTO reportDTO = new ReportDTO();
        reportDTO.setCommentId(commentId);
        checkCommentExist(reportDTO);
        //封装数据
        return ReportVO.builder()
                .id(report.getId())
                .comment(comment.getContent())
                .reason(report.getReason())
                .build();
    }


    /*
     * 判断评论是否存在
     * @param reportDTO
     * @return
     * */
    private Long checkCommentExist(ReportDTO reportDTO) {
        // 判断评论是否存在
        Long commentId = reportDTO.getCommentId();
        if(commentId == null){
            Report report = getById(reportDTO.getId());
            commentId = report.getCommentId();
        }
        Comment comment = commentService.getById(commentId);
        if (comment == null) {
            throw new RuntimeException(MessageConstant.COMMENT_NOT_FOUND);
        }
        return commentId;
    }
}
